﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace FetchAIP
{
    class Download
    {
        // Create a new cookie container
        CookieContainer cookies = new CookieContainer();

        public int DownloadAIP(BackgroundWorker bwDownloader, string baseURL, Queue<pdfLinks> pdfs, string outputPath)
        {
            GetSessionID(baseURL);
            
            int pdfsDownloaded = 0;
            
            foreach (var pdf in pdfs)
            {
                if (bwDownloader.CancellationPending)
                {
                    break;
                }

                string subFolderName;

                // Create a request using a URL that can receive a post. 
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(baseURL + pdf.FileURL);

                //Specify CookieContainer to use
                request.CookieContainer = cookies;

                //Allow redirections for login
                request.AllowAutoRedirect = true;
                
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream receiveStream = response.GetResponseStream();
                
                Byte[] pdfData;
                
                using (var memoryStream = new MemoryStream())
                {
                    receiveStream.CopyTo(memoryStream);
                    pdfData = memoryStream.ToArray();
                }

                response.Close();

                pdfsDownloaded++;

                int slashIndex = pdf.FileURL.IndexOf("/") + 1;

                // subFolderName = "";

                if (pdf.FileURL.StartsWith("pdf/NZ"))
                {
                    subFolderName = "Airport charts\\" + pdf.FileURL.Substring(slashIndex, 4);
                }
                else if (pdf.FileURL.StartsWith("pdf/GEN"))
                {
                    subFolderName = "_AIP_GEN";
                }
                else if (pdf.FileURL.StartsWith("pdf/ENR"))
                {
                    subFolderName = "_AIP_ENR";
                }
                else if (pdf.FileURL.StartsWith("pdf/AD"))
                {
                    subFolderName = "_AIP_AD1";
                }
                else if (pdf.FileURL.StartsWith("pdf/sup"))
                {
                    subFolderName = "_AIP_SUP";
                }
                else
                {
                    subFolderName = "_AIP_UNKNOWN";
                }

                if (!Directory.Exists(outputPath + "\\" + subFolderName))
                    Directory.CreateDirectory(outputPath + "\\" + subFolderName);

                if (pdf.FileURL.Contains("supplements"))
                {
                    File.WriteAllBytes(outputPath + "\\" + subFolderName + "\\" + pdf.FileURL.Replace("pdf/supplements/", string.Empty), pdfData);
                }
                else
                {
                    File.WriteAllBytes(outputPath + "\\" + subFolderName + "\\" + pdf.FileURL.Replace("pdf/", string.Empty), pdfData);
                }
                int pctComplete = (int)(((double)pdfsDownloaded / (double)pdfs.Count()) * 100);
                bwDownloader.ReportProgress(pctComplete);
            }
            return pdfs.Count;
        }

        // Accept T&C and get ASP.NET_SessionId cookie
        public void GetSessionID(string baseURL)
        {
            string viewstate = "";
            string eventvalidation = "";
            string btnAgree = "";
            
            // Download the data to a buffer.
            Byte[] pageData;
            using (var client = new WebClient())
            {
                pageData = client.DownloadData(baseURL);
            }

            string pageHTML = Encoding.ASCII.GetString(pageData);

            // Load page in to html document
            var doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(pageHTML);

            // Crawl page for all links
            var inputs = doc.DocumentNode.SelectNodes(".//input");

            foreach (var input in inputs)
            {
                // If input name equals "__VIEWSTATE", store its value
                if (input.Attributes["name"].Value.Equals("__VIEWSTATE"))
                {
                    viewstate = HttpUtility.UrlEncode(input.Attributes["value"].Value);
                }

                // If input name equals "__EVENTVALIDATION", store its value
                if (input.Attributes["name"].Value.Equals("__EVENTVALIDATION"))
                {
                    eventvalidation = HttpUtility.UrlEncode(input.Attributes["value"].Value);
                }

                // If input name equals "__EVENTVALIDATION", store its value
                if (input.Attributes["name"].Value.Equals("btnAgree"))
                {
                    btnAgree = HttpUtility.UrlEncode(input.Attributes["value"].Value);
                }
            }

            // Create a request using a URL that can receive a post. 
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(baseURL + "Default.aspx");

            // Set the Method property of the request to POST.
            request.Method = "POST";

            // Set the ContentType property of the WebRequest.
            request.ContentType = "application/x-www-form-urlencoded";

            //Specify CookieContainer to use
            request.CookieContainer = cookies;

            // Create POST data and convert it to a byte array.
            string postData = "__VIEWSTATE=" + viewstate + "&__EVENTVALIDATION=" + eventvalidation + "&btnAgree=" + btnAgree;
            byte[] bytes = Encoding.ASCII.GetBytes(postData);

            // Set the ContentLength property of the WebRequest.
            request.ContentLength = bytes.Length;

            // Get the request stream.
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(bytes, 0, bytes.Length);
            dataStream.Close();

            // Get the response.
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        }
    }
}
